﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Input;

namespace PonGun
{
    public enum GunPos
    {
        Top,
        Center,
        Bottom,
    }
    
    public class BatGun : Base2DObject
    {
        public int Barrels { get; set; }
        public Vector2 Offset { get; set; }
        public Bat Bat { get; set; }
        public int Ammo { get; set; }

        public GunPos gunPosition { get; set; }

        public List<Bullet> Shots = new List<Bullet>();
        public List<Bullet> DeadShots = new List<Bullet>();

        TimeSpan lastShot { get; set; }
        public TimeSpan rateOfFire { get; set; }

        public bool CanShoot { get { return (rateOfFire - (DateTime.Now.TimeOfDay - lastShot)) < TimeSpan.Zero && Ammo > 0; } }

        public BatGun(Game1 game, Bat bat, string asset, GunPos gunPos, int barrels = 1, int ammo = 300)
            : base(game)
        {
            rateOfFire = new TimeSpan(0, 0, 0, 1, 0);

            Ammo = ammo;

            Barrels = barrels;

            gunPosition = gunPos;
            Bat = bat;
                        
            Width = (Bat.Width + Bat.halfWidth) * 2;
            Height = Bat.Width * 3;

            Color = bat.Color;

            base.Asset = asset;
        }

        public void Shoot()
        {
            if (CanShoot)
            {
                Ammo--;
                lastShot = DateTime.Now.TimeOfDay;

                Shots.Add(new Bullet(Game, this){ Color = Bat.Player == PlayerIndex.One ? Game1.Player1Color : Game1.Player2Color });
                Shots[Shots.Count - 1].OnCollided = BulletCollided;
                Shots[Shots.Count - 1].OnBulletDied = BulletDied;
                if (Bat.Player == PlayerIndex.One)
                {
                    Game.Content.Load<SoundEffect>("Audio/SFX/laser-01").Play();
                    Shots[Shots.Count - 1].Shoot(new Vector2(-Shots[Shots.Count - 1].MuzzleVelocity, 0));
                }
                else
                {
                    Game.Content.Load<SoundEffect>("Audio/SFX/laser-02").Play();
                    Shots[Shots.Count - 1].Shoot(new Vector2(Shots[Shots.Count - 1].MuzzleVelocity, 0));
                }
            }
        }

        public void BulletDied(Base2DObject obj)
        {
            DeadShots.Add((Bullet)obj);
        }

        void BulletCollided(CollisionData collisionData)
        {
            if (collisionData.Objects[0] is Bullet && Shots.Contains((Bullet)collisionData.Objects[0]))
                BulletDied((Bullet)collisionData.Objects[0]);
            else
            {
                if (collisionData.Objects[1] is Bullet)
                    BulletDied((Bullet)collisionData.Objects[1]);
            }
        }

        public override void Update(GameTime gameTime)
        {
            foreach (Bullet shot in Shots)
                shot.Update(gameTime);

            switch (gunPosition)
            {
                case GunPos.Top:
                    if (Bat.Player == PlayerIndex.One)
                        Offset = new Vector2(-Bat.halfWidth, -Bat.halfHeight);
                    else
                        Offset = new Vector2(Bat.halfWidth, -Bat.halfHeight);
                    break;
                case GunPos.Center:
                    if (Bat.Player == PlayerIndex.One)
                        Offset = new Vector2(-Bat.halfWidth, 0);
                    else
                        Offset = new Vector2(Bat.halfWidth, 0);
                    break;
                case GunPos.Bottom:
                    if (Bat.Player == PlayerIndex.One)
                        Offset = new Vector2(-Bat.halfWidth, Bat.halfHeight);
                    else
                        Offset = new Vector2(Bat.halfWidth, Bat.halfHeight);
                    break;
            }

            Position = Bat.Position + Offset;
            Width = (Bat.Width + Bat.halfWidth) * 2;
            base.Update(gameTime);
            
            foreach (Bullet b in DeadShots)
                Shots.Remove(b);

            DeadShots.Clear();
        }

        public override void Draw(GameTime gameTime)
        {
            
            base.Draw(gameTime);

            foreach (Bullet shot in Shots)
                shot.Draw(gameTime);
        }
    }
}
